package cn.tedu.csmall.order.webapi.service.impl;

import cn.tedu.csmall.cart.service.ICartService;
import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.order.dto.OrderAddDTO;
import cn.tedu.csmall.commons.pojo.order.model.Order;

import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonPage;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.order.service.IOrderService;
import cn.tedu.csmall.order.webapi.mapper.OrderMapper;
import cn.tedu.csmall.stock.service.IStockService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

// order模块的功能会被business模块调用,所以它仍然是生产者,@DubboService要写
@DubboService
@Service
@Slf4j
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;

    // 添加@DubboReference注解,表示当前业务逻辑层要消费其他模块的服务
    // 可以编写当前Nacos中注册的其他业务模块的逻辑层接口
    // 因为Nacos中注册了业务的实现类,所以声明的接口会自动匹配到实现类对象
    // 先添加stock模块的业务逻辑层接口,在添加cart模块
    @DubboReference
    private IStockService dubboStockService;
    @DubboReference
    private ICartService dubboCartService;

    @Override
    public void orderAdd(OrderAddDTO orderAddDTO) {
        // 1.减少订单中商品的库存数(要调用stock模块的功能)
        // 实例化减少库存业务的DTO对象
        StockReduceCountDTO countDTO=new StockReduceCountDTO();
        countDTO.setCommodityCode(orderAddDTO.getCommodityCode());
        countDTO.setReduceCount(orderAddDTO.getCount());
        // 执行dubbo调用完成stock模块减少库存的方法
        dubboStockService.reduceCommodityCount(countDTO);
        // 2.从购物车中删除订单中选择中的商品(要调用cart模块的功能)
        dubboCartService.deleteUserCart(orderAddDTO.getUserId(),
                                        orderAddDTO.getCommodityCode());

        if(Math.random()<0.5){
            throw new CoolSharkServiceException(
                    ResponseCode.INTERNAL_SERVER_ERROR,"随机异常!");
        }

        // 3.将orderAddDTO中的信息新增到数据库订单表中
        // 要将orderAddDTO对象中的属性赋值给Order类型对象的同名属性
        Order order=new Order();
        BeanUtils.copyProperties(orderAddDTO,order);
        // 执行新增
        orderMapper.insertOrder(order);
        log.info("新增订单信息为:{}",order);
    }

    // 分页查询所有订单信息的方法
    // page是页码,pageSize是每页条数
    public JsonPage<Order> getAllOrdersByPage(Integer page, Integer pageSize){
        // PageHelper框架实现分页功能最核心的代码要编写在执行查询的代码之前
        // 使用指定的代码设置要查询的页码和每页的条数
        // 在后面执行查询时,会自动按照这里指定的数据执行分页查询
        // page是页码,1就是查询第一页,pageSize是每页条数
        PageHelper.startPage(page,pageSize);
        // 下面执行查询操作,这个操作会被PageHelper框架在运行的sql语句末尾添加limit语句
        List<Order> list= orderMapper.findAllOrders();

        // list中的数据就是按照分页条件查询出来的某一页的数据
        // 但是分页查询方法返回的并不是list类型的对象,我们也需要获得分页的信息
        // 然后将查询出的数据和分页信息结合返回,这个类型,就是PageInfo

        return JsonPage.restPage(new PageInfo<>(list));

    }





}
